package com.netflexitysolutions.amazonws.sdb.orm.internal.operations;

import java.util.List;
import java.util.concurrent.Callable;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.netflexitysolutions.amazonws.sdb.Domain;
import com.netflexitysolutions.amazonws.sdb.Item;
import com.netflexitysolutions.amazonws.sdb.orm.SimpleDBSession;
import com.netflexitysolutions.amazonws.sdb.orm.SimpleDBSessionListener;
import com.netflexitysolutions.amazonws.sdb.orm.metadata.ItemMetadata;

/**
 * @author netflexity
 *
 * @param <T>
 */
public class Delete<T> implements Callable<Void> {
    
	private static Log logger = LogFactory.getLog(Delete.class.getName());

    private SimpleDBSession session;
    private T record;
    private String id;
    private Class<T> clazz;
    
    /**
     * @param session
     * @param record
     */
    public Delete(SimpleDBSession session, T record) {
        this.session = session;
        this.record = record;
        this.clazz = (Class<T>)record.getClass();
        this.id = session.getId(record).toString();
    }

    /**
	 * @param session
	 * @param clazz
	 * @param id
	 */
	public Delete(SimpleDBSession session, Class<T> clazz, String id) {
		this.session = session;
		this.clazz = clazz;
		this.id = id;
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.Callable#call()
	 */
	public Void call() throws Exception {
        Domain domain = session.getDomain(clazz);
        assert(domain != null);
        
        if(logger.isDebugEnabled()){
        	logger.debug("Deleting item with id: " + id);
        }
        
        // Obtain metadata for this record type.
        ItemMetadata itemMetadata = session.getMetadata(clazz);
        assert(itemMetadata != null);
        
        // Before remove.
        if(record == null){
        	record = (T)itemMetadata.newRecord();
        	itemMetadata.getId().setFieldValue(record, id);
        }
        
        // Before remove.
		List<SimpleDBSessionListener> listeners = session.getFactory().getEntityInterceptors();
		for (SimpleDBSessionListener simpleDBSessionListener : listeners) {
			simpleDBSessionListener.beforeRemove(record);
		}
		
        // Delete from Amazon SimpleDB.
        Item item = new Item();
        item.setIdentifier(id);
        session.getFactory().getDataSource().deleteItem(domain, item);
        
        // After remove.
		for (SimpleDBSessionListener simpleDBSessionListener : listeners) {
			simpleDBSessionListener.afterRemove(record);
		}
        
        // Remove object from cache.
		session.cacheRemove(clazz, id);
		
        return null;
    }
}
